/*
 * @Description: solve linear equations Ax=b
 * @Autor: kaikaima
 * @Date: 2021-03-05 15:30:24
 * @LastEditors: kaikaima
 * @LastEditTime: 2021-04-26 18:38:23
 */
#include <iostream>
#include <cmath>

#ifndef __hhxxttxs_MATRIX__
#define __hhxxttxs_MATRIX__

class Matrix{
    protected:
    unsigned N;
    double **A;
    public:
    Matrix(int _n){
        N=_n;
        A=new double* [_n];
        for(int i=0;i<_n;i++)
            A[i]=new double [_n];
    };
    ~Matrix(){
        for(int i=0;i<N;i++)
            delete A[i];
        delete A;
    };
    void set(double **_a){
        for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            A[i][j]=_a[i][j];
    };
    double* operator*(double* _a) const{
        double* result;
        result=new double [N];
        for(int i=0;i<N;i++){
            result[i]=0;
            for(int j=0;j<N;j++)
                result[i]+=(A[i][j]*_a[j]);
        }
        return result;
    };
    void transposition(){
        for(int i=0;i<N;i++){
            for(int j=0;j<i;j++){
                double tmp=A[i][j];
                A[i][j]=A[j][i];
                A[j][i]=tmp;
            }
        }
    };
    double norm() const{
        double result=0;
        double w[N],v[N],z[N];
        double x[N]={1,0};
        while(true){
            for(int i=0;i<N;i++){
                w[i]=0;
                for(int j=0;j<N;j++)
                    w[i]+=(A[i][j]*x[j]);
            }
            for(int i=0;i<N;i++){
                if(w[i]==0) v[i]=0;
                else if(w[i]>0) v[i]=1;
                else v[i]=-1;
            }
            for(int i=0;i<N;i++){
                z[i]=0;
                for(int j=0;j<N;j++)
                z[i]+=(A[j][i]*v[j]);
            }
            //get ||z||∞ zTx
            int zn=0;
            double zx=0;
            for(int i=1;i<N;i++) if(fabs(z[i])>fabs(z[zn])) zn=i;
            for(int i=0;i<N;i++) zx+=(z[i]*x[i]);

            if(fabs(z[zn])<=zx){
                for(int i=0;i<N;i++)
                result+=fabs(w[i]);
                break;
            }
            else{
                for(int i=0;i<N;i++)
                    x[i]=(i==zn?1:0);
            }
        }
        return result;
    };
};

#else
//DO NOTHING!
#endif